from django.shortcuts import render
from django.views import View
from apps.users.models import User
import logging
import json, re
from django import http
from django_redis import get_redis_connection
from apps.users.models import User
from django.contrib.auth import login, authenticate,logout
import datetime
from django.contrib.auth.mixins import LoginRequiredMixin
from meiduo_mall.utils.encrypt import itsdangerous

logger = logging.getLogger('django')


# Create your views here.

class UsernameCountView(View):
    """判断用户名是否重复注册
             GET http://www.meiduo.site:8000/usernames/itcast/count/
             """

    def get(self, request, username):
        """
               查询用户名对应的记录的个数
               :param username: 用户名
               :return: JSON
               """
        try:
            count = User.objects.filter(username=username).count()

        except Exception as e:
            logger.error(e)
            response = http.JsonResponse({{'code': 400,
                                           'errmsg': '访问数据库失败'}})
            return response

        return http.JsonResponse({'code': '0', 'errmsg': 'OK', 'count': count})


class PhonenumCountView(View):
    '''
    手机重复注册检查
    Get
    mobiles/(?P<mobile>1[3-9]\d{9})/count/
    '''

    def get(self, request, mobile):
        try:
            count = User.objects.filter(mobile=mobile).count()

        except Exception as e:
            response = http.JsonResponse({{'code': 400,
                                           'errmsg': '访问数据库失败'}})
            return response

        return http.JsonResponse({'code': '0', 'errmsg': 'OK', 'count': count})


class UserRegisterView(View):
    def post(self, request):

        '''

请求方法	POST
请求地址	/register/
2.请求参数：json

参数名	类型	是否必传	说明
username	string	是	用户名
password	string	是	密码
password2	string	是	确认密码
mobile	string	是	手机号
sms_code	string	是	短信验证码
allow	bool	是	是否同意用户协议

        '''

        parameters = request.body.decode()
        # 转为字典
        parameters = json.loads(parameters)

        # 接收参数
        username = parameters.get('username')
        password = parameters.get('password')
        password2 = parameters.get('password2')
        mobile = parameters.get('mobile')
        sms_code = parameters.get('sms_code')
        allow = parameters.get('allow')

        # 校验参数
        if not all([username, password, password2, mobile, sms_code, allow]):
            return http.JsonResponse({'code': '400', 'errmsg': '缺少必填信息'})

        # 正则校验

        # 用户名
        if not re.match('', username):
            return http.JsonResponse({'code': '400', 'errmsg': '用户名格式不对'})
            # 密码
        if not re.match('', password):
            return http.JsonResponse({'code': '400', 'errmsg': '密码格式不对'})
            # 手机号
        if not re.match('', mobile):
            return http.JsonResponse({'code': '400', 'errmsg': '手机号格式不对'})

        # 短信验证码校验
        # 链接redis数据库
        redis_conn = get_redis_connection('verify_code')
        # 对比验证码
        try:
            sms_redis = redis_conn.get('sms_%s' % mobile).decode()
        except Exception as e:
            return http.JsonResponse({'code': '400', 'errmsg': '短信失效'})

        if sms_code != sms_redis:
            return http.JsonResponse({'code': '400', 'errmsg': '短信验证码不对'})

        # 创建用户 用户模型类对象.create_user
        try:
            # create_user 还可以返回一个用户对象
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
            print('ok')

        except Exception as e:
            logger(e)
            return http.JsonResponse({'code': '400', 'errmsg': '请重试'})

        response = http.JsonResponse({'code': '0', 'errmsg': 'ok'})
        response.set_cookie('username', username)

        # 状态保持 login(request,user)
        login(request, user)
        return response


class LoginView(View):
    '''
    1.请求方式
选项	方案
请求方法	POST
请求地址	/login/
2.请求参数: json
参数名	类型	是否必传	说明
username	string	是	用户名
password	string	是	密码
remembered	bool	是	是否记住用户
3.响应结果：
字段	说明
登录失败	响应错误提示( code: 400, errmsg: '错误原因' )
登录成功	返回 0 的状态码( code : 0, errmsg: 'ok' )
    '''

    def post(self, request):

        # 接收参数
        parameters = request.body.decode()
        parameters = json.loads(parameters)
        account = parameters.get('username')
        password = parameters.get('password')
        remembered = parameters.get('remembered')

        # 校验参数
        if not all([account, password, remembered]):
            return http.JsonResponse({'code': '400', 'errmsg': '缺少必填信息'})

        # 多账号登录
        if re.match('^1[3456789]\d{9}$',account):
            User.USERNAME_FIELD='mobile'
            print('fuck')

            # 用django自带user检查方法,检测是否登录,authenticate
            # takes from 0 to 1 positional arguments but 2 were given, 这里用不定长参数传,理由如下
            # authenticate(self, request, username=None, password=None, **kwargs):
        user = authenticate(username=account, password=password)
        if not user:
            print('fuck')
            return http.JsonResponse({'code': '400', 'errmsg': '用户不存在'})

        # 状态保持
        login(request, user)

        # 判断是否记住用户 request.session.set_expiry()
        response = http.JsonResponse({'code': '0', 'errmsg': 'ok'})
        # response.set_cookie('username', account)
        if remembered:
            #  If ``value`` is a ``datetime`` or ``timedelta`` object, the session
            #         will expire at that specific future time.

            request.session.set_expiry(None)


        else:
            request.session.set_expiry(0)

        return response


class LogoutView(View):

    def delete(self,request):
        logout(request)
        print('fuck')

        return http.JsonResponse({'code': '0', 'errmsg': 'ok'})


# class LoginisauthMixin(LoginRequiredMixin):
#
#     def dispatch(self, request, *args, **kwargs):
#
#         if not request.user.is_authenticated:
#             print('fuck')
#
#             return http.JsonResponse({'code':400,'errmsg':'还没登录'})


class UserinfoView(View):
    '''
    1.请求方式

选项	方案
请求方法	GET
请求地址	/info/
2.请求参数：无

3.响应结果：JSON

字段	说明
code	状态码
errmsg	错误信息
info_data	返回给前端数据的字典

前端需要的数据

# 这里已经登录的用户用request.user

{
     "code":0,
     "errmsg":"ok",
     "info_data":{
           "username":"zs",
           "mobile": "15144556677",
           "email": "12344566@qq.com",
           "email_active": true
     }
}
    '''

    def get(self,request):

        username = request.user.username
        print(username)
        mobile = request.user.mobile
        email = request.user.email
        email_active = request.user.email_active


        response = http.JsonResponse({"code":0,
     "errmsg":"ok",
                                  'info_data' :{

            "username": username,
            "mobile": mobile,
            "email": email,
            "email_active": email_active

        }
})

        return response


class EmailsaveView(View):

    '''
    1. 添加邮箱接口设计和定义
1.请求方式

选项	方案
请求方法	PUT
请求地址	/emails/
2.请求参数: json 类型

参数名	类型	是否必传	说明
email	string	是	邮箱

3.响应结果：JSON

字段	说明
code	状态码
errmsg	错误信息
    '''

    def put(self,requset):

        email = json.loads(requset.body.decode()).get('email')
        if not email:
            return http.JsonResponse({'code': '400', 'errmsg': '没填邮箱'})


        if not re.match('',email):
            return http.JsonResponse({'code': '400', 'errmsg': '没填邮箱'})

        try:
            requset.user.email = email
            requset.user.save()

        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'code': '400', 'errmsg': '邮箱保存失败'})

        from celery_tasks.sendemail.tasks import sendemail

        token = requset.user.id

        # 加密 token
        token = itsdangerous.serilize(token)

        verify_email = 'http://www.meiduo.site:8080/success_verify_email.html?token=%s'%token

        sendemail.delay(email,verify_email)

        print('ok')


        return http.JsonResponse({'code': '0', 'errmsg': 'ok'})


class VerifyemailView(View):
    '''
    选项	方案
请求方法	PUT
请求地址	/emails/verification/
2.请求参数：查询参数

参数名	类型	是否必传	说明
token	string	是	邮箱激活链接
3.响应结果：Json

字段	说明
code	状态码(有问题400, 没问题0)
errmsg	错误信息
    '''

    def put(self,request):
        # 获取token

        token = request.GET.get('token')

        # 解码token
        token_user_id = itsdangerous.unserilize(token).get('key')

        # 验证token里的user.id 是否为登录用户的user.id
        if token_user_id != request.user.id:
            return http.JsonResponse({'code':400,'errmsg':'fuck you'})
        # 把is_active字段设置为True
        try:
            request.user.is_active = True

        except Exception as e:
            return http.JsonResponse({'code':0,'errmsg':'ok'})